---
title: 计算机系统基础知识
description: 计算机硬件组成、中央处理单元、数据表示、校验码
---


## 硬件系统组成

计算机的基本硬件系统由运算器、控制器、存储器、输入设备和输出设备 5 大部件组成

<RedSpan>运算器、控制器等部件被集成在一起统称为中央处理单元</RedSpan>（Central Processing Unit,CPU）。CPU 是硬件系统的核心,用于<RedSpan>数据的加工处理，能完成各种算术、逻辑运算及控制功能。</RedSpan>。


存储器是计算机系统中的<RedSpan>记忆设备</RedSpan>，分为<RedSpan>内部存储器和外部存储器</RedSpan>。前者速度高、容量小，一般用于临时存放程序、数据及中间结果。而后者容量大、速度慢，可以长期保存程序和数据。

<RedSpan>输入设备和输出设备合称为外部设备</RedSpan>（简称外设），输入设备用于输入原始数据及各种指令，而输出设备则用于输出计算机运行的结果。


## 中央处理单元
### CPU 的功能

前三个是控制器的主要功能，后面一个是运算器的功能。控制器是 CPU 的核心

1. <RedSpan>程序控制</RedSpan>： CPU 通过执行指令来控制程序的执行顺序，这是 CPU 的重要功能。
2. <RedSpan>操作控制</RedSpan>：一条指令功能的实现需要若干操作信号配合来完成，CPU 产生每条指令的操作信号并将其送往对应的部件，控制相应的部件按指令的功能要求进行操作。
3. <RedSpan>时间控制</RedSpan>：CPU 对各种操作进行时间上的控制，即指令执行过程中操作信号的出现时间、持续时间及出现的时间顺序进行严格控制。
4. <RedSpan>数据处理</RedSpan>：CPU 通过对数据进行算术运算及逻辑运算等方式进行加工处理。对数据的加工处理也是 CPU 最根本的任务。

此外，CPU 还需要 <RedSpan>对系统内部和外部的中断（异常）做出响应，进行相应的处理。</RedSpan>


### CPU 的组成

CPU 主要由运算器、控制器、寄存器组和内部总线等部件组成。

运算器由<RedSpan>算术逻辑单元 ALU</RedSpan>(实现对数据的算术和逻辑运算)、<RedSpan>累加寄存器 AC</RedSpan>（运算结果或源操作数的存放区，ALU 可以存放一个操作数）、<RedSpan>数据缓冲寄存器（DR）</RedSpan>（暂时存放内存的指令或数据）和 <RedSpan>状态条件寄存器PSW</RedSpan>（保存指令运行结果的条件码内容，如溢出标志等）组成。<RedSpan>执行所有的算数运算</RedSpan>，如加减乘除等；<RedSpan>执行所有的逻辑运算</RedSpan>，如与、或、非、比较等。


控制器由<RedSpan>指令寄存器 IR</RedSpan>（暂存 CPU 指令）、<RedSpan>程序计数器 PC</RedSpan>（存放指令执行地址）、<RedSpan>地址寄存器 AR</RedSpan>（保存当前 CPU 所访问的内存地址）、<RedSpan>指令译码器 ID</RedSpan>（分析指令操作码）等组成。控制整个 CPU 的工作，最为重要。

:::tip CPU 一条指令的执行过程
根据程序计数器里面的内存地址，从内存里面把需要执行的指令读取到指令寄存器里面执行；
:::

CPU 指令的执行过程分为 取指、分析、执行，执行的过程中如果需要操作数，还需要到内存或者寄存器中去取。

CPU 依据 <RedSpan>指令周期（取指令、分析指令、执行指令）的不同阶段来分区二进制的指令和数据</RedSpan>，因为在指令周期的不同阶段。指令会命令 CPU 分别去取指令或者数据。



## 数据表示
### 进制及进制转换
<RedSpan>二进制符号为 0b,一般表示为 0b0011, 十六进制符号为 0x 或 H,可表示为 0x18F 或 18FH。</RedSpan>（十六进制可表示 0-15，其中 10-15 用 A-F 来表示。）

<RedSpan>R 进制转十进制：</RedSpan>使用位权展开法，用 R 进制的每一位数乘以 R 的 n 次方，n 是变量，从 R 进制的整数最低位开始，依次为 0,1,2,3...累加。

<RedSpan>十进制转 R 进制</RedSpan>： 十进制整数（除以 R 倒取余数），用十进制整数除以 R， 记录每次所得余数，若商不为零，则继续除以 R ，直到商为 0 ，而后将所有余数从下至上记录，排列成从左至右顺序，即为转换后的 R 进制数。


<RedSpan>m 进制转 n 进制</RedSpan>： 先将 m 进制转换为十进制数，再将十进制数转化为 n 进制数，中间需要十进制中转。二进制、八进制、十六进制除外，可以直接互相转换。

<RedSpan>二进制转八进制</RedSpan>：每 <RedSpan>三位二进制数转换为一位八进制数</RedSpan>，二进制数位数不是三的倍数，则在前面补 0（原则是数值不变）

<RedSpan>二进制转十六进制</RedSpan>： 每 <RedSpan>四位二进制数转换为一位十六进制数</RedSpan>，二进制数位数不是四的倍数，则在前面补 0（原则是数值不变）

### 机器数
机器数： 各种<RedSpan>数值在计算机中表示的形式</RedSpan>，其特点是<RedSpan>使用二进制计数制</RedSpan>，数的<RedSpan>符号用 0  和 1 表示，小数点则隐含，不占位置</RedSpan>。

机器数有无符号数和带符号数之分。<RedSpan>无符号数表示正数，没有符号位</RedSpan>。带符号数的最高位为符号位，<RedSpan>正数的符号位是 0 ，负数的符号位是 1</RedSpan>。


定点表示法分为<RedSpan>纯小数和纯整数</RedSpan>两种，其中小数点不占存储位，而是按照以下约定：
* 纯小数：约定小数点的位置在机器数的最高位数值之前。
* 纯整数：约定小数点的位置在机器数的最低数值位之后。

真值：机器数对应的实际数值，即十进制的实际数值。


### 编码方式

原码、反码、补码、移码都是计算机的编码，真值是我们能认识的值。

带符号数有下列编码方式，当真值为 -45 时：

原码：一个数的<RedSpan>正常二进制表示</RedSpan>，最高位表示符号位，数值 0 的原码有两种形式 +0（00000000）和 -0（10000000）。-45 对应原码为 10101101

反码：<RedSpan>正数的反码即原码</RedSpan>；负数的反码是在原码的基础上，<RedSpan>除符号位外，其它各位按位取反</RedSpan>。数值 0 的反码也有两种形式： +0（00000000）和 -0(11111111)。-45 的反码为 11010010。

补码：<RedSpan>正数的补码即原码</RedSpan>；负数的补码是在原码的基础上，<RedSpan>除符号位外，其它各位按位取反，然后末位 +1 ，若有进位则产生进位</RedSpan>。因此数值 0 的补码只有一种形式 +0=-0 = 00000000。-45 对应的补码为 11010011。

移码：用作浮点运算的阶码，<RedSpan>无论正数负数，都是将该原码的补码的首位（符号位）取反得到移动</RedSpan>。-45 对应的移码为：01010011


机器字长为 n 时各种码值的带符号数的取值范围如下（差别在于 0 的表示，原码和反码分 +0 和 -0，补码和移码只有一个 0，因此可以多表示一个数）


| 码制 | 定点整数                             | 定点小数                                   |
|----|----------------------------------|----------------------------------------|
| 原码 | $-(2^{n-1}-1) \sim +(2^{n-1}-1)$ | $-(1-2^{-(n-1)}) \sim +(1-2^{-(n-1)})$ |
| 反码 | $-(2^{n-1}-1) \sim +(2^{n-1}-1)$ | $-(1-2^{-(n-1)}) \sim +(1-2^{-(n-1)})$ |
| 补码 | $-(2^{n-1}) \sim +(2^{n-1}-1)$   | $-1 \sim +(1-2^{-(n-1)})$              |
| 移码 | $-(2^{n-1}) \sim +(2^{n-1}-1)$   | $-1 \sim +(1-2^{-(n-1)})$              |



:::tip
n 位二进制有符号数，数值为 n-1 位,可以表示 $2^{n-1}$ 个数，范围从 0 到 $2^{n-1}-1$。
由于补码和移码没有 -0 ，所以可以多表示一位；小数则是在整数的基础上整体除以 $2^{n-1}$
:::
### 浮点数表示
表示方法为 $N = F \times 2^E$，其中 E 称为阶码，F 称为尾数；类似于十进制的科学计数法。如 $85.125 = 0.85125 \times 10^2 $  二进制如 $101.011 = 0.101011 \times 2^3$

在浮点数的表示中，阶码为带符号的纯整数，尾数为带符号的纯小数，要注意符号占最高位（正数 0 负数 1），其表示格式如下：


<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/image.png"/>

很明显，与科学计数法类似， 一个浮点数的表示方法不是唯一的，浮点数所能<RedSpan>表示的数值范围由阶码确定，所表示的数值精度由尾数确定</RedSpan>。


尾数的表示采用规格化方法，也即带符号尾数的编码必须为 1.0xxx (负数)或者 0.1xxx(正数)，其中 x 可为 0 或 1。

浮点数的运算：
1. 对阶（使两个数阶码相同，小阶向大阶看齐，较小的阶码增加几位，尾数就右移几位，就会导致末尾丢失，即精度丢失）；
2. 尾数计算（相加，若是减运算，则加负数）
3. 结果规格化（即尾数表示规格化，带符号尾数转换为 1.0xxx 或 0.1xxx）。

:::tip
大阶向小阶看齐，尾数就会往左移，高位会丢弃，对精度有很大的影响。末尾丢失可以接受。
:::

## 校验码

码距：就单个编码 A:00 而言，其码距为 1 ，因为只需要改变一位就变成另一个编码。<RedSpan>在两个编码中，从 A 码到 B 码转换所需要改变的位数称为码距</RedSpan>,如 A:00 要转换成 B:11,码距为 2 。一般来说，码距越大，越利于检错和纠错。

### 奇偶校验码
在编码中<RedSpan>增加一位校验位来使编码中 1 的个数为奇数（奇校验）或者偶数（偶校验），从而使码距变为 2</RedSpan>。（校验位+出错位 = 码距）

奇校验：编码中，<RedSpan>含有奇数个 1 </RedSpan>，发送给接收方，接收方收到后，会计算收到的编码有多少个 1，如果是奇数个，则无误，是偶数个，则有误。

偶校验同理，只是编码中有 <RedSpan>偶数个 1 </RedSpan>，所以 <RedSpan>奇偶校验只能检 1 位错，并且无法纠错。</RedSpan>

### CRC 循环冗余校验码

CRC<RedSpan>只能检错，不能纠错。</RedSpan>使用 CRC 编码，需要 <RedSpan>先约定一个生成多项式 G(x)</RedSpan>。生成多项式的最高位和最低位必须是 1。假设原始信息有 m 位，则对应多项式 M(x)。生成校验码的思想就是<RedSpan>在原始信息位后面追加若干校验位，使得追加的信息能被 G(x) 整除。接收方接收到带校验位的信息，然后用 G(x) 整除。余数为 0 ，则没有错误，反之则发生错误。</RedSpan>

> 例子：假设原始信息串为 10110，CRC 的生成多项式为 $G(x) = x^4+x+1$, 求 CRC 校验码。
> 1. 在原始信息位后面添 0 ，假设生成多项式的阶为 r，则在原始信息位后面添加 r 个 0。$G(x)$阶为 4 ，则在原始信息串后加 4 个 0，得到新串 101100000，作为被除数。
> 2. 由多项式得到除数，多项式中 x 的幂指数存在的位置为 1，不存在的位置为 0。本例中， x 的幂指数 0、1、4 都存在，2、3 不存在，因此得到 10011。
> 3. 生成 CRC 校验码，将前两步得到的被除数和除数进行模 2 除法运算（即不进位也不借位的除法运算，也即异或运算。除法过程如下所示）
> <img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/20241019172832.png"/>
> 4. 得到余数 1111。如果余数不足 r，则余数用若干个 0 补齐。如 11 补为 0011 。
> 5. 生成最终发送信息串，将余数添加到原始信息后。10110 添加余数 1111，变为 101101111。发送方将此数据发送给接收方。
> 6. 接收方进行校验。接收方的 CRC 校验过程与生成过程类似，接收方接受了带校验和的帧后，用多项式 $G(x)$（10011） 来除。余数为 0 ，则表示信息无错；否则要求发送方进行重传。

<RedSpan>收发双方需使用相同的生成多项式。</RedSpan>

### 海明码
本质也是<RedSpan>利用奇偶性</RedSpan>来检错和纠错的检验方式，构成方法是在<RedSpan>数据位之间的确定位置插入 k 个校验位</RedSpan>，通过 <RedSpan>扩大码距实现检错和纠错</RedSpan>。


#### 1. **校验位的位数和具体的数据位位数之间的关系**
<RedSpan>所有位都有编号，从最低位编号，从 1 开始递增，校验位位于 2 的 n (n=0,1,2...) 次方中，即处于第 1，2，4，8，16，32，...位上，</RedSpan>其余位才能填充真正的数据位，若信息位 1011，则可知，第 1，2，4 位为校验位，第 3，5，6，7 为数据位，用来从低位开始存放 1011，得出信息位和校验位的分布如下：


| 7     | 6     | 5     | 4     | 3     | 2     | 1     | 位数  |
|-------|-------|-------|-------|-------|-------|-------|-----|
| $I_4$ | $I_3$ | $I_2$ |       | $I_1$ |       |       | 信息位 |
|       |       |       | $r_2$ |       | $r_1$ | $r_0$ | 校验位 |
#### 2. **计算校验码**：
<RedSpan>将所有信息位的编号都拆分成二进制表示</RedSpan>，如下图所示：

$$
\begin{matrix}
7 = 2^2+2^1+2^0, \ \ \  6 = 2^2+2^1, \ \ \  5 = 2^2+2^0, \ \ \  3 = 2^1+2^0; \\
r_2 = I_4 \oplus I_3 \oplus I_2 \\
r_1 = I_4 \oplus I_3 \oplus I_1 \\
r_0 = I_4 \oplus I_2 \oplus I_1 \\
\end{matrix}
$$

上图中，$7 = 4+2+1$ ，表示第 7 由第 4 位校验位（$r_2$） 和第 2 位校验位（$r_1$） 和第 1 位校验位（$r_0$）共同校验，同理，第 6 位数据位 6 = 4+2，第 5 位 5 = 4 + 1，第 3 位 3 = 2+1。
这些 2 的 n 次方都是校验和，可知，第 4 位校验位校验第 7、6、5 三位数据位，因此，第 4 位校验位 r2 等于这三位数据位的值异或，第 2 位和第 1 位校验位计算原理同上。

计算出三个校验位后，可知道最终要发送的海明校验码位 1010101。

这里得出三个校验位是 001 ，默认是偶校验，如果要奇校验，需要将 001 按位取反。所以后面接收方接受后，结果才会是全 1。
#### 3. 检错和纠错原理
接收方接受到海明码之后，会将每一位校验位与其校验的位数分别异或，即做如下三组运算：
$$
\begin{matrix}
r_2 \oplus I_4 \oplus I_3 \oplus I_2 \\
r_1 \oplus I_4 \oplus I_3 \oplus I_1 \\
r_0 \oplus I_4 \oplus I_2 \oplus I_1 \\
\end{matrix}
$$

如果是偶校验，那么 <RedSpan>运算得到的结果应该全是 0 </RedSpan>，如果是奇校验，应该全为 1 ，才是正确，假设是偶校验，且<RedSpan>接受到的数据为 1011101（第四位出错）</RedSpan>，此时运算的结果为：

$$
\begin{matrix}
r_2 \oplus I_4 \oplus I_3 \oplus I_2 = 1 \oplus 1 \oplus 0 \oplus 1 = 1\\
r_1 \oplus I_4 \oplus I_3 \oplus I_1 = 0 \oplus 1 \oplus 0 \oplus 1 = 0 \\
r_0 \oplus I_4 \oplus I_2 \oplus I_1 = 1 \oplus 1 \oplus 1 \oplus 1 = 0 \\
\end{matrix}
$$

这里不全为 0 ，表明传输过程有误，并且按照 $r_2r_1r_0$ 排列为二进制 100,这里指出的就是错误的位数，表示第 100，即第 4 位出错，纠错方法就是将该位逆转。

